package com.ruoyi.produce.process.receiving.service;

import com.ruoyi.DingDing.Domain.DingDingText;
import com.ruoyi.constant.ERPConstant;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.personnel.oa.approve.domain.ApproveDomain;
import com.ruoyi.personnel.oa.approve.mapper.ApproveMapper;
import com.ruoyi.personnel.oa.sequence.service.IApproveSequenceService;
import com.ruoyi.produce.base.shift.service.IProduceShiftInfoService;
import com.ruoyi.produce.process.planoutsource.domain.ProducePlanOutsource;
import com.ruoyi.produce.process.planoutsource.mapper.ProducePlanOutsourceMapper;
import com.ruoyi.produce.process.planself.domain.ProducePlanSelfDto;
import com.ruoyi.produce.process.planself.mapper.ProducePlanSelfMapper;
import com.ruoyi.produce.process.receiving.domain.ReceivingReportCond;
import com.ruoyi.produce.process.receiving.domain.ReceivingReportDomain;
import com.ruoyi.produce.process.receiving.domain.ReceivingReportDto;
import com.ruoyi.produce.process.receiving.domain.productionLogReport;
import com.ruoyi.produce.process.receiving.mapper.ReceivingReportMapper;
import com.ruoyi.produce.process.scheduling.domain.Scheduling;
import com.ruoyi.produce.process.scheduling.mapper.MachineSchedulingMapper;
import com.ruoyi.produce.process.scheduling.mapper.SchedulingMapper;
import com.ruoyi.produce.process.worksheet.domain.ProduceWorkSheet;
import com.ruoyi.produce.process.worksheet.mapper.ProduceWorkSheetMapper;
import com.ruoyi.psi.inventory.record.domain.StockInRecord;
import com.ruoyi.psi.inventory.record.mapper.StockInRecordMapper;
import com.ruoyi.psi.inventory.record.service.IStockInRecordService;
import com.ruoyi.utils.ID.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * 验收单
 * 业务执行层
 *
 * @author Drj 2021/6/28
 * 修改：lsy 2021.8.25
 */
@Service
public class ReceivingReportServiceImpl implements IReceivingReportService {
    @Autowired
    private ReceivingReportMapper receivingReportMapper;
    @Autowired
    private ProduceWorkSheetMapper produceWorkSheetMapper;
    @Autowired
    private ProducePlanSelfMapper producePlanSelfMapper;
    @Autowired
    private IdUtil idUtil;
    @Autowired
    private IApproveSequenceService approveSequenceService;
    @Autowired
    private ApproveMapper approveMapper;
    @Autowired
    private IStockInRecordService stockInRecordService; //入库记录
    @Autowired
    private StockInRecordMapper stockInRecordMapper;//入库记录
    @Autowired
    private ProducePlanOutsourceMapper producePlanOutsourceMapper; //委外
    @Autowired
    private IProduceShiftInfoService shiftInfoService; //班次
    @Autowired
    private SchedulingMapper schedulingMapper; // 排产
    @Autowired
    private MachineSchedulingMapper machineSchedulingMapper;

    /**
     * 查找验收单
     *
     * @param cond
     * @return
     */
    @Override
    public List<ReceivingReportDto> selectReceivingReportList(ReceivingReportCond cond) {
        List<ReceivingReportDto> receivingReportDtos = receivingReportMapper.selectReceivingReportList(cond);
        return receivingReportDtos;
    }

    /**
     * 查找未入库的验收单
     *
     * @param cond
     * @return
     */
    @Override
    public List<ReceivingReportDto> selectNotWarehousedReceivingReportList(ReceivingReportCond cond) {
        return receivingReportMapper.selectNotWarehousedReceivingReportList(cond);
    }

    /**
     * 根据验收单编号查找
     *
     * @param receivingReportId
     * @return
     */
    @Override
    public ReceivingReportDto selectReceivingReportById(String receivingReportId) {
        return receivingReportMapper.selectReceivingReportById(receivingReportId);
    }
    @Override
    public List<ReceivingReportDto> selectReceivingReportBySheetId(String workSheetId) {
        return receivingReportMapper.selectReceivingReportBySheetId(workSheetId);
    }

    /**
     * 新增验收单
     *
     * @param receivingReport
     * @return
     */
    @Override
    public int insertReceivingReport(ReceivingReportDomain receivingReport) throws Exception {
        String receivingReportId = idUtil.createReceivingReportId();
        if (StringUtils.isNotNull(receivingReportMapper.selectReceivingReportById(receivingReportId))) {
            //存在
            return 0;
        }
        receivingReport.setReceivingReportId(receivingReportId); //增加编号
        // 根据来源的不同查询不同的详情
        selectInfoByType(receivingReport);
        receivingReportMapper.insertReceivingReport(receivingReport);
        ApproveDomain approve = new ApproveDomain(receivingReportId, "入库审批", ERPConstant.Approval_Type_Storage, receivingReport.getStaffInspectId()); //新增审批
        approve.setCurrentApprover(approveSequenceService.getLowestRoleId(ERPConstant.Approval_Type_Storage));
        approveMapper.insertApprove(approve);
        Long currentApprover = approve.getCurrentApprover();
        DingDingText dingDingText = new DingDingText();
        dingDingText.BatchRobotText(currentApprover);
        return 1;
    }

    /**
     * 验收单入库
     *
     * @param receivingReport
     * @return
     */
    @Override
    public int receivingReportStorage(ReceivingReportDomain receivingReport) {
        if (!StringUtils.isNotNull(receivingReportMapper.selectReceivingReportById(receivingReport.getReceivingReportId()))) {
            //不存在
            return 0;
        }
        //新增一条入库记录
        StockInRecord stockInRecord = new StockInRecord(receivingReport.getReceivingReportId(), receivingReport.getSourceType(), receivingReport.getStaffInspectId(), receivingReport.getProduceId(), receivingReport.getWarehouseId(), receivingReport.getReceivingReportNumber() - receivingReport.getUnqualifiedNumber());
        stockInRecordService.insertStockInRecord(stockInRecord);
        receivingReportMapper.updateReceivingReport(receivingReport); //修改
        return 1;
    }

    /**
     * 更新验收单
     *
     * @param receivingReport
     * @return
     */
    @Override
    public int updateReceivingReport(ReceivingReportDomain receivingReport) {
        if (!StringUtils.isNotNull(receivingReportMapper.selectReceivingReportById(receivingReport.getReceivingReportId()))) {
            //不存在
            return 0;
        }
        // 根据来源的不同查询不同的详情
        selectInfoByType(receivingReport);
        StockInRecord stockInRecord = stockInRecordMapper.selectStockInRecordByAssociationId(receivingReport.getReceivingReportId());//查询该验收单入库的记录
        if (StringUtils.isNotNull(stockInRecord)) { // 是否有该入库记录
            // 有修改库存
            receivingReport.setWarehousingNumber((receivingReport.getReceivingReportNumber() - receivingReport.getUnqualifiedNumber())); //更新验收单的入库数量
            stockInRecord.setWarehousingNumber((receivingReport.getReceivingReportNumber() - receivingReport.getUnqualifiedNumber())); //更新入库记录的入库数量
            stockInRecordService.updateStockInRecord(stockInRecord);
        }
        return receivingReportMapper.updateReceivingReport(receivingReport);
    }

    /**
     * 删除验收单
     * 仅更新验收单删除标志
     *
     * @param receivingReport
     * @return
     */
    @Override
    public int updateReceivingReportDeleteFlag(ReceivingReportDomain receivingReport) {
        StockInRecord stockInRecord = stockInRecordMapper.selectStockInRecordByAssociationId(receivingReport.getReceivingReportId());//查询该验收单入库的记录
        if (StringUtils.isNotNull(stockInRecord)) { // 是否有该入库记录
            //删除该入库记录
            stockInRecordService.updateStockInRecordDeleteFlag(stockInRecord);
        }
        return receivingReportMapper.updateReceivingReportDeleteFlag(receivingReport);
    }

    /**
     * 查找生产日报表
     *
     * @param cond
     * @return
     */
    @Override
    public List<productionLogReport> selectProductionLogReport(ReceivingReportCond cond) {
        return receivingReportMapper.selectProductionLogReport(cond);
    }

    /**
     * 根据来源的不同查询不同的详情
     */
    public void selectInfoByType(ReceivingReportDomain receivingReport) {
        switch (receivingReport.getSourceType()) {
            case ERPConstant.RECEIVING_WORKSHEET: //加工单
                ProduceWorkSheet produceWorkSheet = produceWorkSheetMapper.selectProduceWorkSheetById(receivingReport.getWorkSheetId());
                //对应自产生产计划信息
                ProducePlanSelfDto producePlanSelf = producePlanSelfMapper.selectProducePlanSelfById(produceWorkSheet.getPlanSelfId());
                if (BigDecimal.valueOf(produceWorkSheet.getWorkSheetNumber()).compareTo(
                        BigDecimal.valueOf(produceWorkSheet.getCompletedNumber())
                                .add(BigDecimal.valueOf(receivingReport.getReceivingReportNumber())
                                        .subtract(BigDecimal.valueOf(receivingReport.getUnqualifiedNumber()))
                                )) < 1) {
                    //计划生产数量小于等于已生产入库数量
                    //加工单
                    produceWorkSheetMapper.updateProduceWorkSheetEndTime(produceWorkSheet); //更新结束时间
                    produceWorkSheetMapper.updateCompletionStatus(produceWorkSheet.getWorkSheetId()); //更新结束标志
                    // 判断是否是注塑车间的加工单，如果有排产记录
                    Scheduling scheduling = schedulingMapper.searchSchedulingByWorkSheetId(shiftInfoService.createShiftInfoId(), produceWorkSheet.getWorkSheetId());
                    if (StringUtils.isNotNull(scheduling)) {
//                        schedulingMapper.updateCompletedStatus(scheduling); //改变手动排产的完成状态
                        machineSchedulingMapper.updateCompletedStatus(scheduling.getMachineId(), scheduling.getWorkSheetId()); //改变自动排产的完成状态
                    }

                }
                if (BigDecimal.valueOf(producePlanSelf.getPlanSelfNumber()).compareTo(
                        BigDecimal.valueOf(producePlanSelf.getCompletedNumber())
                                .add(BigDecimal.valueOf(receivingReport.getReceivingReportNumber())
                                        .subtract(BigDecimal.valueOf(receivingReport.getUnqualifiedNumber()))
                                )) < 1) {
                    //计划生产数量小于等于已生产入库数量
                    //自产生产计划
                    producePlanSelfMapper.updateProducePlanSelfEndTime(producePlanSelf.getPlanSelfId()); //更新结束时间
                    producePlanSelfMapper.updateCompletionStatus(producePlanSelf.getPlanSelfId()); //更新结束标志
                }
                break;
            case ERPConstant.RECEIVING_OUTSOURCEING: //委外
                ProducePlanOutsource producePlanOutsource = producePlanOutsourceMapper.selectProducePlanOutsourceById(receivingReport.getWorkSheetId());
                //对应自产生产计划信息
                producePlanSelf = producePlanSelfMapper.selectProducePlanSelfById(producePlanOutsource.getPlanSelfId());
                if ((receivingReport.getReceivingReportNumber() - receivingReport.getUnqualifiedNumber()) >= (producePlanSelf.getPlanSelfNumber() - producePlanSelf.getCompletedNumber())) {
                    // 验收数量 - 不合格数量 》= 生产计划数量 - 已完成数量
                    producePlanSelfMapper.updateCompletionStatus(producePlanSelf.getPlanSelfId());
                } else if ((receivingReport.getReceivingReportNumber() - receivingReport.getUnqualifiedNumber()) >= (producePlanOutsource.getPlanOutsourceNumber() - producePlanOutsource.getCompletedNumber())) {
                    // 验收数量 - 不合格数量 》= 委外工单数量 - 已完成数量
                    producePlanOutsource.setPlanOutsourceStatus(ERPConstant.COMMON_FINISHED); //委外完成状态
                    producePlanOutsource.setEndTime(new Timestamp(new Date().getTime())); //委外完成时间
                    producePlanOutsourceMapper.updateProducePlanOutsource(producePlanOutsource);
                    producePlanSelfMapper.updateProducePlanSelfEndTime(producePlanSelf.getPlanSelfId()); //更新生产计划结束时间
                }
                break;
            case ERPConstant.RECEIVING_PURCHASE: //采购
                break;
        }
    }
}
